const path = require('path')
const fs = require('fs')
const xlsx = require('node-xlsx')
const { KeyObject } = require('crypto')
// const chalk = require('chalk');

const parentDirectoryPath = path.dirname(__dirname);

const configPath = path.join(parentDirectoryPath, '配置表')
const levelPath = path.join(__dirname, 'level')

const jsonPath = path.join(__dirname, 'jsons')
const classDir = path.join(__dirname, 'class');

function main() {
    parseExcel(configPath, "president");
}
//https://www.cnblogs.com/xsSystem/p/16540205.html
function parseExcel(configPath, dtname) {
    let objT = [];

    let exceltonane = {};
    fs.readdir(configPath, (err, files) => {
        if (err) {
            throw err;
        }

        files.forEach(file => {
            console.log('读取的配置表文件名', file);
            const xlsxDatas = xlsx.parse(fs.readFileSync(configPath + '/' + file));
            exceltonane[file] = [];
            // console.log('读取到的配置表的数据=========================', xlsxDatas);
            for (let i = 0; i < xlsxDatas.length; i++) {
                /**这里的是 每个sheet */
                const xlsxData = xlsxDatas[i];

                //设置表名字
                let tableName = xlsxData.name
                exceltonane[file].push(tableName)

                if (tableName[0] == '!') {
                    tableName = tableName.slice(1)
                }
                const data0 = xlsxData.data[0];
                if (data0 && data0[0] != '类型') {
                    console.warn('\x1b[44m%s\x1b[0m',"这个表里面的切页不用导出" + tableName);
                    continue;
                }
                if (!isNaN(parseInt(tableName[0]))) {
                    console.warn('\x1b[44m%s\x1b[0m',"这个表里面的切页不用导出" + tableName);
                    continue;
                }
                let keys = []
                let dex = [];
                let CS = [];
                let Value0 = [];
                //参数类型
                let types = []

                //第一列

                console.log("tableName", tableName)
                //最后用来写成json的数据
                let json = {
                    '_name': tableName
                }

                // let youhua = tableName.split("_")[1];  //缩减json 

                for (let j = 0; j < 4; j++) {

                    /**这里的data 是每一排 */
                    const data = xlsxData.data[j];
                    // console.log("data",data)

                    if (!data) break

                    if (j == 2) { //表的中文注释
                        json['_des'] = data[0] || ''
                        for (let index = 0; index < data.length; index++) {
                            const element = data[index];
                            dex.push(element)
                        }
                    } else if (j == 1) {//key 这一排是前端后端需要

                        for (let index = 0; index < data.length; index++) {
                            const element = data[index];
                            CS.push(element)
                        }

                        // data.forEach((v, i) => {
                        //     CS.push(v)
                        // })
                        // console.log('CS====', CS)
                    }
                    else if (j == 3) {//key
                        // console.log("datakey==", data)

                        for (let index = 0; index < data.length; index++) {
                            const element = data[index];
                            keys.push(element)
                        }
                        // data.forEach((v, i) => {
                        //     keys.push(v)
                        // })
                        // console.log('keys====', keys)

                    } else if (j == 0) {  //这一排是 参数类型

                        for (let index = 0; index < data.length; index++) {
                            const element = data[index];
                            types.push(element)
                        }

                        // data.forEach((v, i) => {
                        //     types.push(v)
                        // })

                        // console.log('types====', types)
                    }

                }
                // console.log("11")
                let start = 4;
                // console.log("12")
                const data = xlsxData.data[4];
                // console.log("13",data)
                if (data && data[0] == '#') {
                    // console.log("14")
                    start = 5;
                }
                // console.log("15")
                //开始赋值
                let jsonData = {}
                let oneid = "读取"
                for (let k = start; k < xlsxData.data.length; k++) {
                    /**这里的data 是每一排 */
                    const data = xlsxData.data[k];
                    // console.log("k",k)
                    if (!data) break;
                    // console.log("加")
                    let obj = {}
                    // console.log("k2",k)
                    for (let l = 1; l < keys.length && l < types.length; l++) {



                        /**这里的value 是每一排 的每一个*/
                        const value = data[l]
                        // if(l==1){
                        //     console.warn('=================',value)
                        // }
                        const key = keys[l]
                        const type = types[l]
                        const cs = CS[l]
                        if (l == 1) {
                            oneid = key
                        }
                        // //  0要放行  
                        if (l==1&&(value === null || value === undefined|| value === "")) {
                            console.warn('这是一个空行')
                            break
                        }

                        if (key == 'null' || key == undefined) {
                            // console.warn('这是一个空列')
                            continue
                        }

                        // console.warn(value, l)
                        // let cstr = cs.toLowerCase();
                        // console.warn("cstr",cstr);
                        if (cs == 'Both' || cs == 'both' || cs == 'Client' || cs == 'client') {
                            const newValue = parsingValue(type, value)
                            // console.log("key=%s  value=%s  cs=%s i=%s", key, newValue, cs, l);
                            // console.log("value",value);
                            obj[key] = newValue
                        }


                        //console.log(key, newValue, typeof newValue)
                    }

                    if (Object.values(obj).length > 0) {

                        let id = obj['id'] || obj['Id'] || obj[oneid]
                        if(id !== undefined){
                            jsonData[id] = obj
                        }
                        // console.log("key====",id)
                        // console.log("obj====",obj)
                        // 有值
                    }
                    else {
                        // console.warn('obj 里面没有值', tableName, xlsxData.data.length)
                    }

                    //console.log('每一排value的分割线========================');
                }

                //console.log(JSON.stringify(jsonData))
                json["data"] = jsonData

                writeJson(tableName, json)
                //console.log('sheet分割线========================');
                // makeClientClass(configPath,tableName,dex,keys,types,file)

                // console.log(".d.ts 生成 ",tableName)
                objT.push({
                    "configPath": configPath,
                    "tableName": tableName,
                    "dex": dex,
                    "keys": keys,
                    "types": types,
                    "file": file,
                    "Value0": Value0,
                    "CS": CS
                })
            }

            //console.log('文件分割线========================');
        });

        let tem = '';
        let check = {};
        for (let index = 0, l = objT.length; index < l; index++) {
            const element = objT[index];

            if(!check[element.tableName]){
                check[element.tableName] = 1
            }else if(check[element.tableName]){
                console.error('\x1b[33m%s\x1b[0m',"字段名重复==========================================="+element.tableName);
            }


            // console.log(".d.ts 生成 ",element.tableName)
            tem += makeClientClass(element.configPath, element.tableName, element.dex, element.keys, element.types, element.file, element.Value0, element.CS)
        }

        const fw = fs.createWriteStream(path.join(classDir, `${dtname}.d.ts`), { flags: 'w' });
        fw.write(tem);
        fw.close();

        const ename = fs.createWriteStream(path.join(classDir, `表名-切页名对照.txt`), { flags: 'w' });
        ename.write(JSON.stringify(exceltonane));
        ename.close();
    });
}


// 生成一个类结构代码.最终将所有代码写入到一个ts文件中去.
function makeClientClass(dir, className, titles, keys, types, file, Value0, CS) {
    
    let temp = "";
    const clsName = `S${className.charAt(0)}`.toUpperCase() + `${className.substring(1)}` + 'Raw';
    temp += `    /** ${file} */\n`
    temp += `    declare class ${clsName} {\n`;
    keys.forEach((v, i) => {

        let cs = CS[i]
        if (cs == 'Both' || cs == 'both' || cs == 'Client' || cs == 'client') {
            if (types[i] != 'null' && types[i] != undefined) {
                temp += `        /** ${titles[i]} */\n`
                temp += `        public ${v}: ${generateType(types[i])};\n`
            }
        }
    });
    temp += `    }\n\n`;
    //生成枚举
    if (titles[0] == 'enum') {
        temp += `    /** ${file}枚举定义 */\n`
        temp += `    //declare enum ${clsName}enum {\n`;
        Value0.forEach((v, i) => {
            if (Value0[i] != 'null') {
                temp += `//         ${v} = "${v}",\n`
            }
        });
        temp += `//    }\n\n`;
    }



    // const fw = fs.createWriteStream(path.join(classDir, `${clsName}.d.ts`), { flags: 'w' });
    // fw.write(temp);
    // fw.close();

    return temp;
}
function valueSafeCheck(value) {
    if (value === null || value === '' || value === undefined || !(typeof value)) {
        // console.warn('这个key没有填值')
        return false
    }
    return true
}
/**解析数据 */
function parsingValue(type, value) {

    let v = '';
    let safe = valueSafeCheck(value);
    try {
        // console.log("safe",safe)
        switch (type) {
            case 'string':
                v = safe ? (value + '') : '';
                break;
            case 'arry_string':
            case 'array_string':
                v = safe ? JSON.parse(value) : [];
                break;
            case 'array_string2':
                v = safe ? JSON.parse(value) : [];
                break;

            case 'int':
            case 'long':
                v = safe ? Number(value) : 0;
                break;
            case 'array_int2':
            case 'array_long2':
                v = safe ? JSON.parse(value) : [];
                break;
            case 'arry_int':
            case 'array_int':
            case 'arry_long':
            case 'array_long':
                v = safe ? JSON.parse(value) : []
                break;
            case 'bool':
            case 'Bool':
                v = value
                break;
            case 'array_SI': {
                console.log('value==', value)
                v = safe ? JSON.parse(value) : [];
            }
                break;
            default:
                console.warn('这个type没有解析', type);
                break;
        }
    } catch (error) {
        // console.error(chalk.red('解析报错===========================================%s'+error));
        console.error('\x1b[31m%s\x1b[0m',"解析报错==========================================="+value);
    }


    return v;
}

function generateType(type) {
    // if (type == 'string') {
    //     return 'string'

    // } else if (type == 'string[]') {

    //     return 'string[]'

    // } else if (type == 'string[][]') {

    //     return 'string[][]'

    // } else if (type == 'string[][][]') {

    //     return 'string[][][]'

    // } else if (type == 'number' || type == 'float') {
    //     return 'number'

    // } else if (type == 'number[]' || type == 'float[]') {

    //     return 'number[]'

    // } else if (type == 'number[][]' || type == 'float[][]') {

    //     return 'number[][]'

    // } else if (type == 'number[][][]' || type == 'float[][][]') {

    //     return 'number[][][]'

    // } else {
    //     return 'any'
    // }
    let v = 'any';
    switch (type) {
        case 'string':
            v = 'string';
            break;
        case 'array_SI':
            v = 'Array<string|number>'
            break;
        case 'arry_string':
        case 'array_string':
            v = 'string[]'
            break;
        case 'array_string2':
            v = 'string[][]'
            break;

        case 'int':
        case 'long':
            v = 'number'
            break;
        case 'array_int2':
        case 'array_long2':
            v = 'number[][]'
            break;
        case 'arry_int':
        case 'arry_long':
        case 'array_int':
        case 'array_long':
            v = 'number[]'
            break;
        case 'bool':
        case 'Bool':
            v = 'boolean'
            break;
        default:
            console.warn('这个type_class没有解析', type);
            break;
    }
    return v;

}

/**写入json */
function writeJson(fileName, value) {
    const str = JSON.stringify(value);

    const pathName = jsonPath + '/' + fileName + '.json'
    fs.writeFile(pathName, str, function (err) {
        if (err) {
            console.error(err);
        }
        console.log('写入成功 ====', fileName);
    })
}

main()


